Emit a warning when manifest specifies empty dependency constraints
authorFelix Crux <felixc@felixcrux.com>
Mon, 11 Jan 2016 16:08:20 +0000 (11:08 -0500)
committerFelix Crux <felixc@felixcrux.com>
Wed, 20 Jan 2016 03:43:29 +0000 (22:43 -0500)
This warns when encountering dependencies of either of these forms:

  [dependencies]
  foo = {}

and

  [dependencies.foo]

(with nothing further provided).

In the future, this should likely become a hard error.

src/cargo/util/toml.rs
tests/test_bad_config.rs

index ff27b024722faf83dc36d724a727e76230fb21c7..24da8c920e3054bed57286b47135b462473aa4a8 100644 (file)
@@ -515,11 +515,11 @@ impl TomlManifest {
 
             // Collect the deps
             try!(process_dependencies(&mut cx, self.dependencies.as_ref(),
-                                      |dep| dep));
+                                      |dep| dep, &mut warnings));
             try!(process_dependencies(&mut cx, self.dev_dependencies.as_ref(),
-                                      |dep| dep.set_kind(Kind::Development)));
+                                      |dep| dep.set_kind(Kind::Development), &mut warnings));
             try!(process_dependencies(&mut cx, self.build_dependencies.as_ref(),
-                                      |dep| dep.set_kind(Kind::Build)));
+                                      |dep| dep.set_kind(Kind::Build), &mut warnings));
 
             if let Some(targets) = self.target.as_ref() {
                 for (name, platform) in targets.iter() {
@@ -527,19 +527,19 @@ impl TomlManifest {
                                               platform.dependencies.as_ref(),
                                               |dep| {
                         dep.set_only_for_platform(Some(name.clone()))
-                    }));
+                    }, &mut warnings));
                     try!(process_dependencies(&mut cx,
                                               platform.build_dependencies.as_ref(),
                                               |dep| {
                         dep.set_only_for_platform(Some(name.clone()))
                            .set_kind(Kind::Build)
-                    }));
+                    }, &mut warnings));
                     try!(process_dependencies(&mut cx,
                                               platform.dev_dependencies.as_ref(),
                                               |dep| {
                         dep.set_only_for_platform(Some(name.clone()))
                            .set_kind(Kind::Development)
-                    }));
+                    }, &mut warnings));
                 }
             }
         }
@@ -664,7 +664,8 @@ fn validate_bench_name(target: &TomlTarget) -> CargoResult<()> {
 
 fn process_dependencies<F>(cx: &mut Context,
                            new_deps: Option<&HashMap<String, TomlDependency>>,
-                           mut f: F) -> CargoResult<()>
+                           mut f: F,
+                           warnings: &mut Vec<String>) -> CargoResult<()>
     where F: FnMut(DependencyInner) -> DependencyInner
 {
     let dependencies = match new_deps {
@@ -680,6 +681,13 @@ fn process_dependencies<F>(cx: &mut Context,
             }
             TomlDependency::Detailed(ref details) => details.clone(),
         };
+
+        if details.version.is_none() && details.path.is_none() && details.git.is_none() {
+            warnings.push(format!("warning: dependency ({}) specified without providing a local \
+                                   path, Git repository, or version to use. This will be \
+                                   considered an error in future versions", n));
+        }
+
         let reference = details.branch.clone().map(GitReference::Branch)
             .or_else(|| details.tag.clone().map(GitReference::Tag))
             .or_else(|| details.rev.clone().map(GitReference::Rev))
index d38b42802ce26d2210ae03b457b78bb53d80b4df..e7838c237e6c2a8421ff41f9df8f95c2c1e2ebdd 100644 (file)
@@ -1,4 +1,5 @@
 use support::{project, execs};
+use support::registry::Package;
 use hamcrest::assert_that;
 
 fn setup() {}
@@ -387,3 +388,25 @@ test!(unused_keys {
 unused manifest key: target.foo.bar
 "));
 });
+
+test!(empty_dependencies {
+    let p = project("empty_deps")
+    .file("Cargo.toml", r#"
+        [package]
+        name = "empty_deps"
+        version = "0.0.0"
+        authors = []
+
+        [dependencies]
+        foo = {}
+    "#)
+    .file("src/main.rs", "fn main() {}");
+
+    Package::new("foo", "0.0.1").publish();
+
+    assert_that(p.cargo_process("build"),
+                execs().with_status(0).with_stderr_contains("\
+warning: dependency (foo) specified without providing a local path, Git repository, or version \
+to use. This will be considered an error in future versions
+"));
+});